# hello demo1
# langchain使用示例 ，不同于直接使用openai sdk
from asgiref.timeout import timeout
from langchain.chains.question_answering.refine_prompts import chat_qa_prompt_template
from langchain_core.messages import HumanMessage, SystemMessage
from langchain_openai import ChatOpenAI
import langchain
import openai
from mChatAI import env_conf
from multiprocessing import Process, Queue, freeze_support
'''
LangChain作为一个应用开发框架，需要集成各种不同的大模型，如上述OpenAI的GPT系列模型调用示例，通过Message数据输入规范，定义不同的role，即system、user和assistant来区分对话过程，但对于其他大模型，并不意味这一定会遵守这种输入输出及角色的定义，所以LangChain的做法是，因为Chat Model基于消息而不是原始文本，LangChain目前就抽象出来的消息类型有 AIMessage 、 HumanMessage 、 SystemMessage 、 FunctionMessage 和 ChatMessage ，但大多时候我们只需要处理 HumanMessage 、 AIMessage 和 SystemMessage，即：
- SystemMessage ：用于启动 AI 行为，作为输入消息序列中的第一个传入。
- HumanMessage ：表示来自与聊天模型交互的人的消息。
- AIMessage ：表示来自聊天模型的消息。这可以是文本，也可以是调用工具的请求。
'''


class ai_model:

    def __init__(self,model_name,key,url,sysmessage,message,stream=False):
        self.model_name = model_name
        self.key = key
        self.url = url
        self.sysmessage = env_conf.basicprompt+sysmessage
        self.message = message
        self.stream = stream

    # 测试模型是否正常可用
    def check(self):
        print('langchain :', langchain.__version__)
        print('openai :', openai.__version__)

        client = openai.OpenAI(base_url="http://chatapi.littlewheat.com/v1", api_key=env_conf.openai_key)
        completion = client.chat.completions.create(
            # model="gpt-4o-mini", # this field is currently unused
            model="gpt-3.5-turbo",
            messages=[
                {"role": "system", "content": "你是一个乐于助人的智能AI小助手"},
                {"role": "user", "content": "你好，请你介绍一下你自己"}
            ],
            temperature=0.7,
        )
        print(completion.choices[0].message.content)  # 输出文案

    def chat_api(self):
        messages = [SystemMessage(content=self.sysmessage),
                    HumanMessage(content=self.message),]

        chat = ChatOpenAI(model_name=self.model_name, api_key=self.key, base_url=self.url,request_timeout=100,timeout=100)
        ans = chat.invoke(messages)


        if self.stream:
            # stream 流输出
            for chunk in chat.stream(messages):
                print(chunk.content, end="", flush=True)
        else:
            print(self.model_name,ans.content)
            return ans.content

    def run(self):
        pass



def run_chat_api_in_process(model_name, key, url, sysmessage, message, stream, result_queue):
    """包装函数用于多进程调用"""
    try:
        ai = ai_model(model_name, key, url, sysmessage, message, stream)
        result = f'<span style="color: green;">{model_name}</span>'+'\n'+ai.chat_api()
        if result_queue:
            result_queue.put(result)
    except Exception as e:
            result_queue.put('err'+model_name)

def run(sysprompt,prompt):
    processes = []
    result_queue = Queue()
    for i in[env_conf.deepseek,env_conf.qwen3_coder,env_conf.gpt4o]:
        p = Process(
            target=run_chat_api_in_process,
            args=(
                i[0],i[1],i[2],
                sysprompt,  # sysmessage sysmessage,message
                prompt,  False,   result_queue  # 结果队列
            )
        )
        p.start()
        processes.append(p)  # 保存进程对象
    # 等待所有进程完成
    for p in processes:
        p.join()

    # 获取所有结果
    results = []
    while not result_queue.empty():
        results.append(result_queue.get())

    return  {'ai1':results[0],'ai2':results[1] ,'ai3':results[2]}

if __name__ == '__main__':
    ai_model(env_conf.gpt4o[0],env_conf.gpt4o[1],env_conf.gpt4o[2],'你叫小明','你是谁').chat_api()
    pass